package com.sxds.wn.controller;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractCommandController;

import com.sxds.wn.IConstants;
import com.sxds.wn.service.IService;
import com.sxds.wn.service.Request;
import com.sxds.wn.service.Response;


/**
 * Description: <p>集成实现Spring的AbstractCommandController抽象接口</p>
 * Content Desc:<p>所有实现AbstractCommandController的子类必须集成该抽象类<p>
 * Copy Right of Personal Tangtao 2007-2020
 * @author Andy
 * @version 1.0 Create Date:@2008-12-2
 */
public abstract class BaseCommandController extends AbstractCommandController implements IConstants {
	
	//日志处理
	private Log log = LogFactory.getLog(getClass());
	//处理成功后返回的ViewName
	private String successView;
	//错误处理页面的View
	private String failedView;
	//服务接口请求对象
	protected Request andyRequest;
	//服务接口返回对象
	protected Response andyResponse;
	//服务接口
	private IService service;
	
	/**
	 * 默认构造方法
	 */
	public BaseCommandController() {
		super();
	}

	/**
	 * 默认构造方法
	 */
	public BaseCommandController(Class commandClass) {
		super(commandClass);
	}

	/**
	 * 默认构造方法
	 */
	public BaseCommandController(Class commandClass, String commandName) {
		super(commandClass, commandName);
	}

	/**
	 * 保存错误信息
	 * @param request
	 * @param error
	 */
	public void saveError(HttpServletRequest request, String error) {
		List errors = (List) request.getSession().getAttribute(PAGE_ERRORS_MESSAGES_KEY);
		if (errors == null) {
			errors = new ArrayList();
		}
		errors.add(error);
		request.getSession().setAttribute(PAGE_ERRORS_MESSAGES_KEY, errors);
	}

	/**
	 * 保存成功信息或其他信息
	 * @param request
	 * @param msg
	 */
	@SuppressWarnings("unchecked")
	public void saveMessage(HttpServletRequest request, String msg) {
		List messages = (List) request.getSession().getAttribute(PAGE_SUCCESS_MESSAGES_KEY);
		if (messages == null) {
			messages = new ArrayList();
		}
		messages.add(msg);
		request.getSession().setAttribute(PAGE_SUCCESS_MESSAGES_KEY, messages);
	}
	
	/* (non-Javadoc)
	 * @see org.springframework.web.servlet.mvc.AbstractCommandController#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, org.springframework.validation.BindException)
	 */
	@Override
	protected ModelAndView handle(HttpServletRequest httpRequest,HttpServletResponse httpResponse, 
								  Object command,BindException bindexception) throws Exception {
		return processService(httpRequest, httpResponse, command, bindexception);
	}
	
	/**
	 * 处理具体业务逻辑
	 * @param httpRequest javax.servlet.http.HttpServletRequest
	 * @param httpResponse javax.servlet.http.HttpServletResponse
	 * @throws Exception 异常
	 */
	protected ModelAndView processService(HttpServletRequest httpRequest,HttpServletResponse httpResponse,
										  Object command,BindException bindexception) throws Exception {
		this.andyRequest = new Request(httpRequest);
		this.setRequestParamer();
		ModelAndView modelAndView = new ModelAndView(this.getSuccessView());
		try{
			this.andyRequest.getRequestAttributes().put("command", command);
			this.andyRequest.getRequestAttributes().put("bindException", bindexception);
			this.andyResponse = service.process(this.andyRequest);
			Map pageAttributes = this.andyResponse.getPageAttributes();
			modelAndView.addObject((this.andyResponse.isOk()? "success":"failure"), true);
			if( !pageAttributes.isEmpty() ){
				Iterator it = pageAttributes.keySet().iterator();
				while( it.hasNext() ){
					String key = (String)it.next();
					Object value = pageAttributes.get(key);
					//httpRequest.setAttribute(key, value);
					modelAndView.addObject(key, value);
				}
			}
			if( this.andyResponse.isOk() ){
				//将讲结果保存在request对象中和ModelAndView
				this.processResponse();
			}else{
				this.saveError(httpRequest, andyResponse.getResponseMessage());
				if( this.failedView!=null && !"".equals(this.failedView)){
					modelAndView.setViewName(this.failedView);
				}
			}
		}catch(Exception ex){
			log.error("处理请求错误：",ex);
			this.saveError(httpRequest, "调用业务接口错误：" + ex.getMessage());
			httpRequest.setAttribute("exception", ex);
			throw new Exception("处理请求错误："+ex);
		}
		return modelAndView;
	}
	
	
	
	/**
	 * 子类可以定义覆盖此方法,设置调用的业务的请求参数
	 */
	protected abstract void setRequestParamer();
	
	/**
	 * 子类可以实现处理返回的结构，如把想要的对象写入到HttpServletRequest对象
	 */
	protected abstract void processResponse();

	/**
	 * @return the successView
	 */
	public String getSuccessView() {
		return successView;
	}

	/**
	 * @param successView the successView to set
	 */
	public void setSuccessView(String successView) {
		this.successView = successView;
	}

	/**
	 * @return the service
	 */
	public IService getService() {
		return service;
	}

	/**
	 * @param service the service to set
	 */
	public void setService(IService service) {
		this.service = service;
	}

	/**
	 * @return the failedView
	 */
	public String getFailedView() {
		return failedView;
	}

	/**
	 * @param failedView the failedView to set
	 */
	public void setFailedView(String failedView) {
		this.failedView = failedView;
	}

}
